#pragma once
#ifndef CLIB_TCP_STREAM_H
#define CLIB_TCP_STREAM_H

#include "clib_type.h"
#include "clib_tcp_buffer.h"
#ifndef __USE_MISC
#define __USE_MISC
#endif 
#include <netinet/tcp.h>
#ifdef __USE_MISC
#undef __USE_MISC
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct tcphdr               tcp_hdr_t;

enum tcp_state
{
	TCP_ST_CLOSED		   = 0, 
	TCP_ST_LISTEN		   = 1, 
	TCP_ST_SYN_SENT		= 2, 
	TCP_ST_SYN_RCVD		= 3,  
	TCP_ST_ESTABLISHED	= 4, 
	TCP_ST_FIN_WAIT1	   = 5, 
	TCP_ST_FIN_WAIT2	   = 6, 
	TCP_ST_CLOSE_WAIT	   = 7, 
	TCP_ST_CLOSING		   = 8, 
	TCP_ST_LAST_ACK		= 9, 
	TCP_ST_TIME_WAIT	   = 10
};

typedef enum
{
   TCP_FLAG_FIN = 0x01,
   TCP_FLAG_SYN = 0x02,
   TCP_FLAG_RST = 0x04,
   TCP_FLAG_PSH = 0x08,
   TCP_FLAG_ACK = 0x10,
   TCP_FLAG_URG = 0x20
} clib_tcp_flags;

typedef enum
{
   TCP_OPTION_END                 = 0,
   TCP_OPTION_NOP                 = 1,
   TCP_OPTION_MAX_SEGMENT_SIZE    = 2,
   TCP_OPTION_WINDOW_SCALE_FACTOR = 3,
   TCP_OPTION_SACK_PERMITTED      = 4,
   TCP_OPTION_SACK                = 5,
   TCP_OPTION_TIMESTAMP           = 8
} clib_tcp_option_e;


typedef struct
{
   u08_t kind;
   u08_t size;
   u08_t data[];
} tcp_opt_t clib_aligend(1);

/**
 * @brief SACK block
 */
typedef struct
{
   u32_t left_edge;
   u32_t right_edge;
} clib_tcp_sack_t;

typedef struct clib_tcp_stream_s
{
   u32_t descriptor;
   //systime_t timeout;
   u16_t tcp_state;              ///<TCP 状态 
   u08_t ttl;                    ///<Time-to-live value for unicast datagrams
   u08_t multicast_ttl;          ///<Time-to-live value for multicast datagrams

   u16_t smss;                   ///<发送端最大分段大小
   u16_t rmss;                   ///<接收端最大分段大小
   u32_t iss;                    ///<初始发送序列号
   u32_t irs;                    ///<初始接收序列号
   
   tcp_buffer_t *send_buffer;    ///<TCPbuffer缓存
   //clib_queue_t snd_list;
   u32_t snd_una;                ///<发送出去还没被确认的数据
   u32_t snd_nxt;                ///<发送数据下一个序列号
   u16_t snd_user;               ///<已缓冲但尚未发送的数据量
   u16_t snd_wnd;                ///<发送窗口的大小
   u16_t snd_max_wnd;            ///<最大发送窗口
   u32_t snd_wl1;                ///<用于上次窗口更新的段序列号
   u32_t snd_wl2;                ///<用于上次窗口更新的段确认号
   tcp_buffer_t *recv_buffer;    ///<接收数据buffer
   //clib_queue_t rcv_list;
   u32_t rcv_nxt;                ///<接收下一个序列号
   u16_t rcv_user;               ///<已接收但尚未消耗的数据数
   u16_t rcv_wnd;                ///<接收窗口
   
} tcp_stream_t;

#ifdef __cplusplus
}
#endif

#endif